#!/usr/bin/env python
# coding=utf-8

from google.appengine.ext import webapp
from google.appengine.ext.webapp import RequestHandler
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp import util

from model.model import Member, Location
from v2ex.babel.security import get_current_member, GetIP
from v2ex.babel.ua import *
from v2ex.babel.ext import captcha
import hashlib
import datetime
import config
from v2ex.babel.ext.cookies import Cookies
from google.appengine.api.datastore_types import GeoPt
import urllib2
from json.json import ReadException
from json import json

class MainHandler(RequestHandler):
    '''
    classdocs
    '''
    def get(self):
        member = get_current_member(self)
        if member:
            location = db.GqlQuery("SELECT * FROM Location WHERE member = :1", member)[0]
            template_values = {}
            template_values['member']= member
            template_values['email']= member.email
            template_values['username']= member.username
            template_values['location']= "shenzhen"
            template_values['latitude']= location.location.lat
            template_values['longitude']= location.location.lon
            template_values['page_title']= "主页"
            path = os.path.join(os.path.dirname(__file__), 'static', 'html', 'index.html')
            output = template.render(path, template_values)
            self.response.out.write(output)
        else:
            self.redirect("/signin")
        
class SignupHandler(RequestHandler):
    def getLocation(self,ip):
            try:
                URL='http://ip.json.dotcloud.com/json/'+ip.strip()
                tempFile = urllib2.urlopen(URL).read()
                jsonobj = json.read(tempFile)
                return GeoPt(float(jsonobj['latitude']),float(jsonobj['longitude']))
            except ReadException:
                return GeoPt(23,110)
            except KeyError:
                return GeoPt(23,114)
    
    def get(self):
        chtml = captcha.displayhtml(
            public_key = config.recaptcha_public_key,
            use_ssl = False,
            error = None)
        browser = detect(self.request)
        template_values = {}
        template_values['page_title'] = "PassBy" + u' › 注册'
        template_values['errors'] = 0
        template_values['captchahtml'] = chtml
        if browser['ios']:
            path = os.path.join(os.path.dirname(__file__), 'static', 'api', 'signup.html')
        else:
            path = os.path.join(os.path.dirname(__file__), 'static', 'html', 'signup.html')
        output = template.render(path, template_values)
        self.response.out.write(output)
        pass
    
    def post(self):
        username = self.request.get('username').strip()
        password = self.request.get('password')
        email = self.request.get('email')
        usernameError = 0
        passwordError = 0
        emailError = 0
        usernameErrorMessage = ['',
                                '您输入的用户名长度小于3个字符',
                                '您输入的用户名长度大于12个字符',
                                '您输入的用户名已存在',
                                '您输入的用户名格式非法，只能使用字母，数字与下划线']
        passwordErrorMessage = ['',
                                '您输入的密码长度小于6位数',
                                '您输入的密码长度大于12位']
        emailErrorMessage = ['',
                             'email不能为空',
                             '您输入的email长度大于32位',
                             '您输入的email已经存在',
                             '您输入的email格式不正确']
        if len(username)<3:
            usernameError = 1#用户名过短
        elif len(username)>12:
            usernameError = 2#用户名过长
        else:
            if (re.search('^[a-zA-Z0-9\_]+$', username)):
                q = db.GqlQuery('SELECT __key__ FROM Member WHERE username = :1', username)
                if (q.count() > 0):
                    usernameError = 3#用户名已存在
            else:
                usernameError = 4#用户名非法
        if len(password)<6:
            passwordError = 1#密码过短
        elif len(password)>12:
            passwordError = 2#密码过长
        if (len(email) == 0):
            emailError = 1#email不能为空
        else:
            if (len(email) > 32):
                emailError = 2#email过长
            else:
                p = re.compile(r"(?:^|\s)[-a-z0-9_.]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE)
                if (p.search(email)):
                    q = db.GqlQuery('SELECT __key__ FROM Member WHERE email = :1', email)
                    if (q.count() > 0):
                        emailError = 3#email已经存在
                else:
                    emailError = 4#email格式不正确
        
        if (usernameError + passwordError + emailError)>0:
            templateData = {}
            templateData['username'] = username
            templateData['password'] = password
            templateData['email'] = email
            templateData['usernameErrorMessage'] = usernameErrorMessage[usernameError]
            templateData['passwordErrorMessage'] = passwordErrorMessage[passwordError]
            templateData['emailErrorMessage'] = emailErrorMessage[emailError]
            path = os.path.join(os.path.dirname(__file__),'static','html','signup.html')
            output = template.render(path,templateData)
            self.response.out.write(output)
        else:
            p_sha1 = hashlib.sha1(password).hexdigest()
            newmember = Member(username=username,password=p_sha1,email=email)
            newmember.ip = GetIP(self)
            newmember.auth = hashlib.sha1(str(newmember.username) + ':' + newmember.password).hexdigest()
            self.response.headers['Set-Cookie'] = 'auth=' + newmember.auth + '; expires=' + (datetime.datetime.now() + datetime.timedelta(days=365)).strftime("%a, %d-%b-%Y %H:%M:%S GMT") + '; path=/'
            newmember.put()
            location = Location(member=newmember)
            location.location = self.getLocation(newmember.ip)
            location.put()
            self.redirect('/')
            
class SigninHandler(RequestHandler):
    def get(self):
        site = "Passby"
        member = get_current_member(self)
        if member:
            self.response.out.write("您已经有帐号登录，请退出当前帐户再登录")#TODO 提示页面
            return
        destination = self.request.get("dest")
        browser = detect(self.request)
        template_values = {}
        template_values['site'] = site
        template_values['page_title'] = site
        template_values['dest'] = destination
        #template_values['system_version'] = SYSTEM_VERSION
        #l10n = GetMessages(self, member, site)
        #template_values['l10n'] = l10n
        errors = 0
        template_values['errors'] = errors
        if browser['ios']:
            path = os.path.join(os.path.dirname(__file__), 'static', 'api', 'signin.html')
        else:
            path = os.path.join(os.path.dirname(__file__), 'static', 'html', 'signin.html')
        output = template.render(path, template_values)
        self.response.out.write(output)
 
    def post(self):
        member = False
        destination = self.request.get("dest")
        browser = detect(self.request)
        template_values = {}
        template_values['site'] = "Passby"
        template_values['page_title'] = "Passby" + u' › 登入'
        #template_values['system_version'] = SYSTEM_VERSION
        u = self.request.get('u').strip()
        p = self.request.get('p').strip()
        #l10n = GetMessages(self, member, site)
        #template_values['l10n'] = l10n
        errors = 0
        error_messages = ['', '请输入用户名和密码', '你输入的用户名或密码不正确']
        if (len(u) > 0 and len(p) > 0):
            p_sha1 = hashlib.sha1(p).hexdigest()
            if '@' in u:
                q = db.GqlQuery("SELECT * FROM Member WHERE email = :1 AND password = :2", u, p_sha1)
            else:
                q = db.GqlQuery("SELECT * FROM Member WHERE username = :1 AND password = :2", u, p_sha1)
            if (q.count() == 1):
                member = q[0]
                self.response.headers['Set-Cookie'] = 'auth=' + member.auth + '; expires=' + (datetime.datetime.now() + datetime.timedelta(days=365)).strftime("%a, %d-%b-%Y %H:%M:%S GMT") + '; path=/'
                if destination:
                    self.redirect(destination)
                else:
                    self.redirect('/')
                return
            else:
                errors = 2
        else:
            errors = 1
        template_values['u'] = u
        template_values['p'] = p
        template_values['errors'] = errors
        template_values['error_message'] = error_messages[errors]
        if browser['ios']:
            path = os.path.join(os.path.dirname(__file__), 'tpl', 'mobile', 'signin.html')
        else:
            path = os.path.join(os.path.dirname(__file__), 'static', 'html', 'signin.html')
        output = template.render(path, template_values)
        self.response.out.write(output)
            
class SignoutHandler(RequestHandler):
    def get(self):#TODO改成post，用js实现
        browser = detect(self.request)
        template_values = {}
        template_values['page_title'] = "Lucky" + u' › 登出'
        cookies = Cookies(self, max_age = 86400, path = '/')
        del cookies['auth']
        if browser['ios']:
            path = os.path.join(os.path.dirname(__file__), 'static', 'api', 'signout.html')
        else:
            path = os.path.join(os.path.dirname(__file__), 'static', 'html', 'signout.html')
        output = template.render(path, template_values)
        self.response.out.write(output)
            
def main():
    application = webapp.WSGIApplication([('/',MainHandler),
                                          ('/signup',SignupHandler),
                                          ('/signin',SigninHandler),
                                          ('/signout',SignoutHandler)],
                                         debug=True)
    util.run_wsgi_app(application)
        
if __name__ == '__main__':
    main()
        